home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / lib / python2.6 / trace.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2009-11-11  |  23KB  |  737 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. '''program/module to trace Python program or function execution
  5.  
  6. Sample use, command line:
  7.   trace.py -c -f counts --ignore-dir \'$prefix\' spam.py eggs
  8.   trace.py -t --ignore-dir \'$prefix\' spam.py eggs
  9.   trace.py --trackcalls spam.py eggs
  10.  
  11. Sample use, programmatically
  12.   import sys
  13.  
  14.   # create a Trace object, telling it what to ignore, and whether to
  15.   # do tracing or line-counting or both.
  16.   tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix,], trace=0,
  17.                     count=1)
  18.   # run the new command using the given tracer
  19.   tracer.run(\'main()\')
  20.   # make a report, placing output in /tmp
  21.   r = tracer.results()
  22.   r.write_results(show_missing=True, coverdir="/tmp")
  23. '''
  24. import linecache
  25. import os
  26. import re
  27. import sys
  28. import threading
  29. import time
  30. import token
  31. import tokenize
  32. import types
  33. import gc
  34.  
  35. try:
  36.     import cPickle
  37.     pickle = cPickle
  38. except ImportError:
  39.     import pickle
  40.  
  41.  
  42. def usage(outfile):
  43.     outfile.write("Usage: %s [OPTIONS] <file> [ARGS]\n\nMeta-options:\n--help                Display this help then exit.\n--version             Output version information then exit.\n\nOtherwise, exactly one of the following three options must be given:\n-t, --trace           Print each line to sys.stdout before it is executed.\n-c, --count           Count the number of times each line is executed\n                      and write the counts to <module>.cover for each\n                      module executed, in the module's directory.\n                      See also `--coverdir', `--file', `--no-report' below.\n-l, --listfuncs       Keep track of which functions are executed at least\n                      once and write the results to sys.stdout after the\n                      program exits.\n-T, --trackcalls      Keep track of caller/called pairs and write the\n                      results to sys.stdout after the program exits.\n-r, --report          Generate a report from a counts file; do not execute\n                      any code.  `--file' must specify the results file to\n                      read, which must have been created in a previous run\n                      with `--count --file=FILE'.\n\nModifiers:\n-f, --file=<file>     File to accumulate counts over several runs.\n-R, --no-report       Do not generate the coverage report files.\n                      Useful if you want to accumulate over several runs.\n-C, --coverdir=<dir>  Directory where the report files.  The coverage\n                      report for <package>.<module> is written to file\n                      <dir>/<package>/<module>.cover.\n-m, --missing         Annotate executable lines that were not executed\n                      with '>>>>>> '.\n-s, --summary         Write a brief summary on stdout for each file.\n                      (Can only be used with --count or --report.)\n-g, --timing          Prefix each line with the time since the program started.\n                      Only used while tracing.\n\nFilters, may be repeated multiple times:\n--ignore-module=<mod> Ignore the given module(s) and its submodules\n                      (if it is a package).  Accepts comma separated\n                      list of module names\n--ignore-dir=<dir>    Ignore files in the given directory (multiple\n                      directories can be joined by os.pathsep).\n" % sys.argv[0])
  44.  
  45. PRAGMA_NOCOVER = '#pragma NO COVER'
  46. rx_blank = re.compile('^\\s*(#.*)?$')
  47.  
  48. class Ignore:
  49.     
  50.     def __init__(self, modules = None, dirs = None):
  51.         if not modules:
  52.             pass
  53.         self._mods = []
  54.         if not dirs:
  55.             pass
  56.         self._dirs = []
  57.         self._dirs = map(os.path.normpath, self._dirs)
  58.         self._ignore = {
  59.             '<string>': 1 }
  60.  
  61.     
  62.     def names(self, filename, modulename):
  63.         if self._ignore.has_key(modulename):
  64.             return self._ignore[modulename]
  65.         for mod in self._mods:
  66.             if mod == modulename:
  67.                 self._ignore[modulename] = 1
  68.                 return 1
  69.             n = len(mod)
  70.             if mod == modulename[:n] and modulename[n] == '.':
  71.                 self._ignore[modulename] = 1
  72.                 return 1
  73.         
  74.         if filename is None:
  75.             self._ignore[modulename] = 1
  76.             return 1
  77.         for d in self._dirs:
  78.             if filename.startswith(d + os.sep):
  79.                 self._ignore[modulename] = 1
  80.                 return 1
  81.         
  82.         self._ignore[modulename] = 0
  83.         return 0
  84.  
  85.  
  86.  
  87. def modname(path):
  88.     '''Return a plausible module name for the patch.'''
  89.     base = os.path.basename(path)
  90.     (filename, ext) = os.path.splitext(base)
  91.     return filename
  92.  
  93.  
  94. def fullmodname(path):
  95.     '''Return a plausible module name for the path.'''
  96.     comparepath = os.path.normcase(path)
  97.     longest = ''
  98.     for dir in sys.path:
  99.         dir = os.path.normcase(dir)
  100.         if comparepath.startswith(dir) and comparepath[len(dir)] == os.sep:
  101.             if len(dir) > len(longest):
  102.                 longest = dir
  103.             
  104.         len(dir) > len(longest)
  105.     
  106.     if longest:
  107.         base = path[len(longest) + 1:]
  108.     else:
  109.         base = path
  110.     base = base.replace(os.sep, '.')
  111.     if os.altsep:
  112.         base = base.replace(os.altsep, '.')
  113.     
  114.     (filename, ext) = os.path.splitext(base)
  115.     return filename
  116.  
  117.  
  118. class CoverageResults:
  119.     
  120.     def __init__(self, counts = None, calledfuncs = None, infile = None, callers = None, outfile = None):
  121.         self.counts = counts
  122.         if self.counts is None:
  123.             self.counts = { }
  124.         
  125.         self.counter = self.counts.copy()
  126.         self.calledfuncs = calledfuncs
  127.         if self.calledfuncs is None:
  128.             self.calledfuncs = { }
  129.         
  130.         self.calledfuncs = self.calledfuncs.copy()
  131.         self.callers = callers
  132.         if self.callers is None:
  133.             self.callers = { }
  134.         
  135.         self.callers = self.callers.copy()
  136.         self.infile = infile
  137.         self.outfile = outfile
  138.         if self.infile:
  139.             
  140.             try:
  141.                 (counts, calledfuncs, callers) = pickle.load(open(self.infile, 'rb'))
  142.                 self.update(self.__class__(counts, calledfuncs, callers))
  143.             except (IOError, EOFError, ValueError):
  144.                 err = None
  145.                 print >>sys.stderr, 'Skipping counts file %r: %s' % (self.infile, err)
  146.             except:
  147.                 None<EXCEPTION MATCH>(IOError, EOFError, ValueError)
  148.             
  149.  
  150.         None<EXCEPTION MATCH>(IOError, EOFError, ValueError)
  151.  
  152.     
  153.     def update(self, other):
  154.         '''Merge in the data from another CoverageResults'''
  155.         counts = self.counts
  156.         calledfuncs = self.calledfuncs
  157.         callers = self.callers
  158.         other_counts = other.counts
  159.         other_calledfuncs = other.calledfuncs
  160.         other_callers = other.callers
  161.         for key in other_counts.keys():
  162.             counts[key] = counts.get(key, 0) + other_counts[key]
  163.         
  164.         for key in other_calledfuncs.keys():
  165.             calledfuncs[key] = 1
  166.         
  167.         for key in other_callers.keys():
  168.             callers[key] = 1
  169.         
  170.  
  171.     
  172.     def write_results(self, show_missing = True, summary = False, coverdir = None):
  173.         '''
  174.         @param coverdir
  175.         '''
  176.         if self.calledfuncs:
  177.             print 
  178.             print 'functions called:'
  179.             calls = self.calledfuncs.keys()
  180.             calls.sort()
  181.             for filename, modulename, funcname in calls:
  182.                 print 'filename: %s, modulename: %s, funcname: %s' % (filename, modulename, funcname)
  183.             
  184.         
  185.         if self.callers:
  186.             print 
  187.             print 'calling relationships:'
  188.             calls = self.callers.keys()
  189.             calls.sort()
  190.             lastfile = lastcfile = ''
  191.             for pfile, pmod, pfunc in calls:
  192.                 (cfile, cmod, cfunc) = None
  193.                 if pfile != lastfile:
  194.                     print 
  195.                     print '***', pfile, '***'
  196.                     lastfile = pfile
  197.                     lastcfile = ''
  198.                 
  199.                 if cfile != pfile and lastcfile != cfile:
  200.                     print '  -->', cfile
  201.                     lastcfile = cfile
  202.                 
  203.                 print '    %s.%s -> %s.%s' % (pmod, pfunc, cmod, cfunc)
  204.             
  205.         
  206.         per_file = { }
  207.         for filename, lineno in self.counts.keys():
  208.             lines_hit = per_file[filename] = per_file.get(filename, { })
  209.             lines_hit[lineno] = self.counts[(filename, lineno)]
  210.         
  211.         sums = { }
  212.         for filename, count in per_file.iteritems():
  213.             if filename == '<string>':
  214.                 continue
  215.             
  216.             if filename.startswith('<doctest '):
  217.                 continue
  218.             
  219.             if filename.endswith(('.pyc', '.pyo')):
  220.                 filename = filename[:-1]
  221.             
  222.             if coverdir is None:
  223.                 dir = os.path.dirname(os.path.abspath(filename))
  224.                 modulename = modname(filename)
  225.             else:
  226.                 dir = coverdir
  227.                 if not os.path.exists(dir):
  228.                     os.makedirs(dir)
  229.                 
  230.                 modulename = fullmodname(filename)
  231.             if show_missing:
  232.                 lnotab = find_executable_linenos(filename)
  233.             else:
  234.                 lnotab = { }
  235.             source = linecache.getlines(filename)
  236.             coverpath = os.path.join(dir, modulename + '.cover')
  237.             (n_hits, n_lines) = self.write_results_file(coverpath, source, lnotab, count)
  238.             if summary and n_lines:
  239.                 percent = int(100 * n_hits / n_lines)
  240.                 sums[modulename] = (n_lines, percent, modulename, filename)
  241.                 continue
  242.         
  243.         if summary and sums:
  244.             mods = sums.keys()
  245.             mods.sort()
  246.             print 'lines   cov%   module   (path)'
  247.             for m in mods:
  248.                 (n_lines, percent, modulename, filename) = sums[m]
  249.                 print '%5d   %3d%%   %s   (%s)' % sums[m]
  250.             
  251.         
  252.         if self.outfile:
  253.             
  254.             try:
  255.                 pickle.dump((self.counts, self.calledfuncs, self.callers), open(self.outfile, 'wb'), 1)
  256.             except IOError:
  257.                 err = None
  258.                 print >>sys.stderr, "Can't save counts files because %s" % err
  259.             except:
  260.                 None<EXCEPTION MATCH>IOError
  261.             
  262.  
  263.         None<EXCEPTION MATCH>IOError
  264.  
  265.     
  266.     def write_results_file(self, path, lines, lnotab, lines_hit):
  267.         '''Return a coverage results file in path.'''
  268.         
  269.         try:
  270.             outfile = open(path, 'w')
  271.         except IOError:
  272.             err = None
  273.             print >>sys.stderr, 'trace: Could not open %r for writing: %s- skipping' % (path, err)
  274.             return (0, 0)
  275.  
  276.         n_lines = 0
  277.         n_hits = 0
  278.         for i, line in enumerate(lines):
  279.             lineno = i + 1
  280.             if lineno in lines_hit:
  281.                 outfile.write('%5d: ' % lines_hit[lineno])
  282.                 n_hits += 1
  283.                 n_lines += 1
  284.             elif rx_blank.match(line):
  285.                 outfile.write('       ')
  286.             elif lineno in lnotab and PRAGMA_NOCOVER not in lines[i]:
  287.                 outfile.write('>>>>>> ')
  288.                 n_lines += 1
  289.             else:
  290.                 outfile.write('       ')
  291.             outfile.write(lines[i].expandtabs(8))
  292.         
  293.         outfile.close()
  294.         return (n_hits, n_lines)
  295.  
  296.  
  297.  
  298. def find_lines_from_code(code, strs):
  299.     '''Return dict where keys are lines in the line number table.'''
  300.     linenos = { }
  301.     line_increments = [ ord(c) for c in code.co_lnotab[1::2] ]
  302.     table_length = len(line_increments)
  303.     docstring = False
  304.     lineno = code.co_firstlineno
  305.     for li in line_increments:
  306.         lineno += li
  307.         if lineno not in strs:
  308.             linenos[lineno] = 1
  309.             continue
  310.         []
  311.     
  312.     return linenos
  313.  
  314.  
  315. def find_lines(code, strs):
  316.     '''Return lineno dict for all code objects reachable from code.'''
  317.     linenos = find_lines_from_code(code, strs)
  318.     for c in code.co_consts:
  319.         if isinstance(c, types.CodeType):
  320.             linenos.update(find_lines(c, strs))
  321.             continue
  322.     
  323.     return linenos
  324.  
  325.  
  326. def find_strings(filename):
  327.     '''Return a dict of possible docstring positions.
  328.  
  329.     The dict maps line numbers to strings.  There is an entry for
  330.     line that contains only a string or a part of a triple-quoted
  331.     string.
  332.     '''
  333.     d = { }
  334.     prev_ttype = token.INDENT
  335.     f = open(filename)
  336.     for ttype, tstr, start, end, line in tokenize.generate_tokens(f.readline):
  337.         if ttype == token.STRING:
  338.             if prev_ttype == token.INDENT:
  339.                 (sline, scol) = start
  340.                 (eline, ecol) = end
  341.                 for i in range(sline, eline + 1):
  342.                     d[i] = 1
  343.                 
  344.             
  345.         
  346.         prev_ttype = ttype
  347.     
  348.     f.close()
  349.     return d
  350.  
  351.  
  352. def find_executable_linenos(filename):
  353.     '''Return dict where keys are line numbers in the line number table.'''
  354.     
  355.     try:
  356.         prog = open(filename, 'rU').read()
  357.     except IOError:
  358.         err = None
  359.         print >>sys.stderr, 'Not printing coverage data for %r: %s' % (filename, err)
  360.         return { }
  361.  
  362.     code = compile(prog, filename, 'exec')
  363.     strs = find_strings(filename)
  364.     return find_lines(code, strs)
  365.  
  366.  
  367. class Trace:
  368.     
  369.     def __init__(self, count = 1, trace = 1, countfuncs = 0, countcallers = 0, ignoremods = (), ignoredirs = (), infile = None, outfile = None, timing = False):
  370.         """
  371.         @param count true iff it should count number of times each
  372.                      line is executed
  373.         @param trace true iff it should print out each line that is
  374.                      being counted
  375.         @param countfuncs true iff it should just output a list of
  376.                      (filename, modulename, funcname,) for functions
  377.                      that were called at least once;  This overrides
  378.                      `count' and `trace'
  379.         @param ignoremods a list of the names of modules to ignore
  380.         @param ignoredirs a list of the names of directories to ignore
  381.                      all of the (recursive) contents of
  382.         @param infile file from which to read stored counts to be
  383.                      added into the results
  384.         @param outfile file in which to write the results
  385.         @param timing true iff timing information be displayed
  386.         """
  387.         self.infile = infile
  388.         self.outfile = outfile
  389.         self.ignore = Ignore(ignoremods, ignoredirs)
  390.         self.counts = { }
  391.         self.blabbed = { }
  392.         self.pathtobasename = { }
  393.         self.donothing = 0
  394.         self.trace = trace
  395.         self._calledfuncs = { }
  396.         self._callers = { }
  397.         self._caller_cache = { }
  398.         self.start_time = None
  399.         if timing:
  400.             self.start_time = time.time()
  401.         
  402.         if countcallers:
  403.             self.globaltrace = self.globaltrace_trackcallers
  404.         elif countfuncs:
  405.             self.globaltrace = self.globaltrace_countfuncs
  406.         elif trace and count:
  407.             self.globaltrace = self.globaltrace_lt
  408.             self.localtrace = self.localtrace_trace_and_count
  409.         elif trace:
  410.             self.globaltrace = self.globaltrace_lt
  411.             self.localtrace = self.localtrace_trace
  412.         elif count:
  413.             self.globaltrace = self.globaltrace_lt
  414.             self.localtrace = self.localtrace_count
  415.         else:
  416.             self.donothing = 1
  417.  
  418.     
  419.     def run(self, cmd):
  420.         import __main__ as __main__
  421.         dict = __main__.__dict__
  422.         if not self.donothing:
  423.             sys.settrace(self.globaltrace)
  424.             threading.settrace(self.globaltrace)
  425.         
  426.         
  427.         try:
  428.             exec cmd in dict, dict
  429.         finally:
  430.             if not self.donothing:
  431.                 sys.settrace(None)
  432.                 threading.settrace(None)
  433.             
  434.  
  435.  
  436.     
  437.     def runctx(self, cmd, globals = None, locals = None):
  438.         if globals is None:
  439.             globals = { }
  440.         
  441.         if locals is None:
  442.             locals = { }
  443.         
  444.         if not self.donothing:
  445.             sys.settrace(self.globaltrace)
  446.             threading.settrace(self.globaltrace)
  447.         
  448.         
  449.         try:
  450.             exec cmd in globals, locals
  451.         finally:
  452.             if not self.donothing:
  453.                 sys.settrace(None)
  454.                 threading.settrace(None)
  455.             
  456.  
  457.  
  458.     
  459.     def runfunc(self, func, *args, **kw):
  460.         result = None
  461.         if not self.donothing:
  462.             sys.settrace(self.globaltrace)
  463.         
  464.         
  465.         try:
  466.             result = func(*args, **kw)
  467.         finally:
  468.             if not self.donothing:
  469.                 sys.settrace(None)
  470.             
  471.  
  472.         return result
  473.  
  474.     
  475.     def file_module_function_of(self, frame):
  476.         code = frame.f_code
  477.         filename = code.co_filename
  478.         if filename:
  479.             modulename = modname(filename)
  480.         else:
  481.             modulename = None
  482.         funcname = code.co_name
  483.         clsname = None
  484.         return (filename, modulename, funcname)
  485.  
  486.     
  487.     def globaltrace_trackcallers(self, frame, why, arg):
  488.         '''Handler for call events.
  489.  
  490.         Adds information about who called who to the self._callers dict.
  491.         '''
  492.         if why == 'call':
  493.             this_func = self.file_module_function_of(frame)
  494.             parent_func = self.file_module_function_of(frame.f_back)
  495.             self._callers[(parent_func, this_func)] = 1
  496.         
  497.  
  498.     
  499.     def globaltrace_countfuncs(self, frame, why, arg):
  500.         '''Handler for call events.
  501.  
  502.         Adds (filename, modulename, funcname) to the self._calledfuncs dict.
  503.         '''
  504.         if why == 'call':
  505.             this_func = self.file_module_function_of(frame)
  506.             self._calledfuncs[this_func] = 1
  507.         
  508.  
  509.     
  510.     def globaltrace_lt(self, frame, why, arg):
  511.         """Handler for call events.
  512.  
  513.         If the code block being entered is to be ignored, returns `None',
  514.         else returns self.localtrace.
  515.         """
  516.         if why == 'call':
  517.             code = frame.f_code
  518.             filename = frame.f_globals.get('__file__', None)
  519.             if filename:
  520.                 modulename = modname(filename)
  521.                 if modulename is not None:
  522.                     ignore_it = self.ignore.names(filename, modulename)
  523.                     if not ignore_it:
  524.                         if self.trace:
  525.                             print ' --- modulename: %s, funcname: %s' % (modulename, code.co_name)
  526.                         
  527.                         return self.localtrace
  528.                 
  529.             else:
  530.                 return None
  531.         filename
  532.  
  533.     
  534.     def localtrace_trace_and_count(self, frame, why, arg):
  535.         if why == 'line':
  536.             filename = frame.f_code.co_filename
  537.             lineno = frame.f_lineno
  538.             key = (filename, lineno)
  539.             self.counts[key] = self.counts.get(key, 0) + 1
  540.             if self.start_time:
  541.                 print '%.2f' % (time.time() - self.start_time),
  542.             
  543.             bname = os.path.basename(filename)
  544.             print '%s(%d): %s' % (bname, lineno, linecache.getline(filename, lineno)),
  545.         
  546.         return self.localtrace
  547.  
  548.     
  549.     def localtrace_trace(self, frame, why, arg):
  550.         if why == 'line':
  551.             filename = frame.f_code.co_filename
  552.             lineno = frame.f_lineno
  553.             if self.start_time:
  554.                 print '%.2f' % (time.time() - self.start_time),
  555.             
  556.             bname = os.path.basename(filename)
  557.             print '%s(%d): %s' % (bname, lineno, linecache.getline(filename, lineno)),
  558.         
  559.         return self.localtrace
  560.  
  561.     
  562.     def localtrace_count(self, frame, why, arg):
  563.         if why == 'line':
  564.             filename = frame.f_code.co_filename
  565.             lineno = frame.f_lineno
  566.             key = (filename, lineno)
  567.             self.counts[key] = self.counts.get(key, 0) + 1
  568.         
  569.         return self.localtrace
  570.  
  571.     
  572.     def results(self):
  573.         return CoverageResults(self.counts, infile = self.infile, outfile = self.outfile, calledfuncs = self._calledfuncs, callers = self._callers)
  574.  
  575.  
  576.  
  577. def _err_exit(msg):
  578.     sys.stderr.write('%s: %s\n' % (sys.argv[0], msg))
  579.     sys.exit(1)
  580.  
  581.  
  582. def main(argv = None):
  583.     import getopt as getopt
  584.     if argv is None:
  585.         argv = sys.argv
  586.     
  587.     
  588.     try:
  589.         (opts, prog_argv) = getopt.getopt(argv[1:], 'tcrRf:d:msC:lTg', [
  590.             'help',
  591.             'version',
  592.             'trace',
  593.             'count',
  594.             'report',
  595.             'no-report',
  596.             'summary',
  597.             'file=',
  598.             'missing',
  599.             'ignore-module=',
  600.             'ignore-dir=',
  601.             'coverdir=',
  602.             'listfuncs',
  603.             'trackcalls',
  604.             'timing'])
  605.     except getopt.error:
  606.         msg = None
  607.         sys.stderr.write('%s: %s\n' % (sys.argv[0], msg))
  608.         sys.stderr.write("Try `%s --help' for more information\n" % sys.argv[0])
  609.         sys.exit(1)
  610.  
  611.     trace = 0
  612.     count = 0
  613.     report = 0
  614.     no_report = 0
  615.     counts_file = None
  616.     missing = 0
  617.     ignore_modules = []
  618.     ignore_dirs = []
  619.     coverdir = None
  620.     summary = 0
  621.     listfuncs = False
  622.     countcallers = False
  623.     timing = False
  624.     for opt, val in opts:
  625.         if opt == '--help':
  626.             usage(sys.stdout)
  627.             sys.exit(0)
  628.         
  629.         if opt == '--version':
  630.             sys.stdout.write('trace 2.0\n')
  631.             sys.exit(0)
  632.         
  633.         if opt == '-T' or opt == '--trackcalls':
  634.             countcallers = True
  635.             continue
  636.         
  637.         if opt == '-l' or opt == '--listfuncs':
  638.             listfuncs = True
  639.             continue
  640.         
  641.         if opt == '-g' or opt == '--timing':
  642.             timing = True
  643.             continue
  644.         
  645.         if opt == '-t' or opt == '--trace':
  646.             trace = 1
  647.             continue
  648.         
  649.         if opt == '-c' or opt == '--count':
  650.             count = 1
  651.             continue
  652.         
  653.         if opt == '-r' or opt == '--report':
  654.             report = 1
  655.             continue
  656.         
  657.         if opt == '-R' or opt == '--no-report':
  658.             no_report = 1
  659.             continue
  660.         
  661.         if opt == '-f' or opt == '--file':
  662.             counts_file = val
  663.             continue
  664.         
  665.         if opt == '-m' or opt == '--missing':
  666.             missing = 1
  667.             continue
  668.         
  669.         if opt == '-C' or opt == '--coverdir':
  670.             coverdir = val
  671.             continue
  672.         
  673.         if opt == '-s' or opt == '--summary':
  674.             summary = 1
  675.             continue
  676.         
  677.         if opt == '--ignore-module':
  678.             for mod in val.split(','):
  679.                 ignore_modules.append(mod.strip())
  680.             
  681.             continue
  682.         
  683.         if opt == '--ignore-dir':
  684.             for s in val.split(os.pathsep):
  685.                 s = os.path.expandvars(s)
  686.                 s = s.replace('$prefix', os.path.join(sys.prefix, 'lib', 'python' + sys.version[:3]))
  687.                 s = s.replace('$exec_prefix', os.path.join(sys.exec_prefix, 'lib', 'python' + sys.version[:3]))
  688.                 s = os.path.normpath(s)
  689.                 ignore_dirs.append(s)
  690.             
  691.             continue
  692.         
  693.         if not 0:
  694.             raise AssertionError, 'Should never get here'
  695.     
  696.     if listfuncs:
  697.         if count or trace:
  698.             _err_exit('cannot specify both --listfuncs and (--trace or --count)')
  699.         
  700.     if not count and trace and report and listfuncs or countcallers:
  701.         _err_exit('must specify one of --trace, --count, --report, --listfuncs, or --trackcalls')
  702.     
  703.     if report and no_report:
  704.         _err_exit('cannot specify both --report and --no-report')
  705.     
  706.     if report and not counts_file:
  707.         _err_exit('--report requires a --file')
  708.     
  709.     if no_report and len(prog_argv) == 0:
  710.         _err_exit('missing name of file to run')
  711.     
  712.     if report:
  713.         results = CoverageResults(infile = counts_file, outfile = counts_file)
  714.         results.write_results(missing, summary = summary, coverdir = coverdir)
  715.     else:
  716.         sys.argv = prog_argv
  717.         progname = prog_argv[0]
  718.         sys.path[0] = os.path.split(progname)[0]
  719.         t = Trace(count, trace, countfuncs = listfuncs, countcallers = countcallers, ignoremods = ignore_modules, ignoredirs = ignore_dirs, infile = counts_file, outfile = counts_file, timing = timing)
  720.         
  721.         try:
  722.             t.run('execfile(%r)' % (progname,))
  723.         except IOError:
  724.             err = None
  725.             _err_exit('Cannot run file %r because: %s' % (sys.argv[0], err))
  726.         except SystemExit:
  727.             pass
  728.  
  729.         results = t.results()
  730.         if not no_report:
  731.             results.write_results(missing, summary = summary, coverdir = coverdir)
  732.         
  733.  
  734. if __name__ == '__main__':
  735.     main()
  736.  
  737.